﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace SharpSoda.Message
{
    public static class JsonHelper
    {
        private static IMessageCodec m_MessageCodec = null;

        static JsonHelper()
        {
            if (m_MessageCodec == null) m_MessageCodec = new JsonMessageCodec();
        }

        public static void SetMessageCodec(IMessageCodec codec)
        {
            if (codec != null) m_MessageCodec = codec;
        }

        public static IMessageCodec GetMessageCodec()
        {
            return m_MessageCodec;
        }

        public static string ToString(object obj)
        {
            try
            {
                return m_MessageCodec.ToString(obj);
            }
            catch
            {
                return "";
            }
        }

        //public static string Format(string str)
        //{
        //    return JsonFormatterPlus.JsonFormatter.Format(str);
        //}

        public static string ToString<T>(T obj) where T : class
        {
            try
            {
                return m_MessageCodec.ToString<T>(obj);
            }
            catch
            {
                return "";
            }
        }

        public static T FromString<T>(string str) where T : class 
        {
            try
            {
                if (str == null || str.Length <= 0) return null;
                else return m_MessageCodec.FromString<T>(str);
            }
            catch
            {
                return null;
            }
        }

        public static T Clone<T>(T src) where T : class 
        {
            string str = m_MessageCodec.ToString<T>(src);
            return m_MessageCodec.FromString<T>(str);
        }

        public static void CopyProperties<T>(T src, T dst, List<string> exclude = null)
        {
            if (src != null && dst != null)
            {
                foreach (PropertyDescriptor item in TypeDescriptor.GetProperties(src))
                {
                    if (exclude != null && exclude.Contains(item.Name)) continue;
                    item.SetValue(dst, item.GetValue(src));
                }
            }
        }

        public static void SetPropertyValue(object obj, string propName, object propValue)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(propName);
            if (propertyInfo != null)
            {
                propertyInfo.SetValue(obj, Convert.ChangeType(propValue, propertyInfo.PropertyType), null);
            }
        }

        public static object GetPropertyValue(object obj, string propName)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(propName);
            if (propertyInfo != null)
            {
                return propertyInfo.GetValue(obj, null);
            }
            return null;
        }

        public static T FromFile<T>(string filepath) where T : class 
        {
            try
            {
                string str = "";
                if (File.Exists(filepath)) str = File.ReadAllText(filepath);
                if (str.Length > 0) return FromString<T>(str);
                else return null;
            }
            catch
            {
                return null;
            }
        }

        public static List<T> FromFolder<T>(string dir) where T : class 
        {
            List<T> result = new List<T>();
            List<string> files = new List<string>();
            if (Directory.Exists(dir)) files.AddRange(Directory.GetFiles(dir));
            foreach (string filepath in files)
            {
                T obj = FromFile<T>(filepath);
                if (obj != null) result.Add(obj);
            }
            return result;
        }

        
    }
}
